package com.kuaimacode.kframework.code.template;

import com.github.pagehelper.PageInfo;
import com.kuaimacode.kframework.code.domain.Generate;
import com.kuaimacode.kframework.code.enums.FieldQuery;
import com.kuaimacode.kframework.code.utils.CodeUtil;
import com.kuaimacode.kframework.code.utils.GenerateUtil;
import com.kuaimacode.kframework.code.utils.TemplateUtil;
import com.kuaimacode.kframework.util.ToolUtil;
import com.kuaimacode.kframework.common.JsonResult;
import com.kuaimacode.kframework.constants.PageConstants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;

import javax.security.auth.Subject;
import java.nio.file.FileAlreadyExistsException;
import java.util.List;

/**
 * @author Administrator
 * @date 2018/10/24
 */
public class ControllerTemplate {

    /**
     * 生成需要导入的包
     */
    private static void genImport(Generate generate) {
        String tableEntity = generate.getBasic().getTableEntity();
        String genModule = generate.getBasic().getGenModule();
        String pacageName = TemplateUtil.getPath(generate) + ".mybatis.models."+ genModule + "." + tableEntity;
        //CodeUtil.importLine(pacageName);
        //处理实体包名
        pacageName = pacageName.replaceAll("admin.*mybatis","mybatis");
        CodeUtil.importLine(pacageName);
        CodeUtil.importLine(pacageName.replace(".models.", ".mapper.")+"Mapper");

        //CodeUtil.importLine(TemplateUtil.getPath(generate) + ".admin.services." + tableEntity + "Service");
        CodeUtil.importLine(TemplateUtil.getPathNew(generate, "services") +"." + tableEntity + "Service");
       // CodeUtil.importLine(TemplateUtil.getPath(generate) + ".validator." + tableEntity + "Form");

        CodeUtil.importLine(PageInfo.class);
        CodeUtil.importLine(JsonResult.class);
        CodeUtil.importLine(PageConstants.class);
        //CodeUtil.importLine(SecurityUtils.class);
        CodeUtil.importLine(Subject.class);
        CodeUtil.importLine(Autowired.class);
        CodeUtil.importLine(ModelMap.class);
        CodeUtil.importLine(Controller.class);
        CodeUtil.importLine("org.springframework.web.bind.annotation.*");
        CodeUtil.importLine(List.class);
    }

    /**
     * 生成类体
     */
    private static void getClazzBody(Generate generate) {
        // 构建数据
        String var = ToolUtil.lowerFirst(generate.getBasic().getTableEntity());
        String obj = generate.getBasic().getTableEntity();
        String title = generate.getBasic().getGenTitle();
        String module = generate.getBasic().getGenModule();
        String filePath = ControllerTemplate.class.getResource("").getPath()
                + ControllerTemplate.class.getSimpleName() + ".code";

        // 生成Class前部分
        String clazzTarget = TemplateUtil.getTemplate(filePath, "Class");
        clazzTarget = clazzTarget.replace("#{var}", var);
        clazzTarget = clazzTarget.replace("#{obj}", obj);
        clazzTarget = clazzTarget.replace("#{title}", title);
        CodeUtil.append(clazzTarget).append(CodeUtil.lineBreak);

        // 生成index列表
        if(generate.getTemplate().isIndex()){
            String indexTarget = TemplateUtil.getTemplate(filePath, "index");
            indexTarget = indexTarget.replace("#{var}", var);
            indexTarget = indexTarget.replace("#{obj}", obj);
            indexTarget = indexTarget.replace("#{title}", title);
            indexTarget = indexTarget.replace("#{module}", module);
            // 生成模糊查询字段
            StringBuilder matcher = new StringBuilder();
            generate.getFields().forEach(field -> {
                if(field.getQuery() == FieldQuery.Like.getCode()){
                    matcher.append(".").append(CodeUtil.lineBreak);
                    matcher.append("\t\t\t\twithMatcher(\"").append(field.getName()).append("\", match -> match.contains())");
                }
            });

            indexTarget = indexTarget.replace("#{matcher}", matcher);
            CodeUtil.append(indexTarget).append(CodeUtil.lineBreak);
        }

        // 添加操作和编辑操作
        if(generate.getTemplate().isAdd()){
            String addTarget = TemplateUtil.getTemplate(filePath, "add");
            addTarget = addTarget.replace("#{var}", var);
            addTarget = addTarget.replace("#{obj}", obj);
            addTarget = addTarget.replace("#{module}", module);
            CodeUtil.append(addTarget).append(CodeUtil.lineBreak);
        }

        // 详细页面
        if(generate.getTemplate().isDetail()){
            String detailTarget = TemplateUtil.getTemplate(filePath, "detail");
            detailTarget = detailTarget.replace("#{var}", var);
            detailTarget = detailTarget.replace("#{obj}", obj);
            detailTarget = detailTarget.replace("#{module}", module);
            CodeUtil.append(detailTarget).append(CodeUtil.lineBreak);
        }

        // 删除操作
        if(generate.getTemplate().isIndex()) {
            String statusTarget = TemplateUtil.getTemplate(filePath, "delete");
            statusTarget = statusTarget.replace("#{var}", var);
            statusTarget = statusTarget.replace("#{obj}", obj);
            CodeUtil.append(statusTarget).append(CodeUtil.lineBreak);
        }

        // 结束类
        CodeUtil.lineNo("}");
    }

    /**
     * 生成控制器模板
     */
    public static String generate(Generate generate) {
        CodeUtil.create();
        CodeUtil.setPackageName(TemplateUtil.getPackageNew(generate, "controller"));
        CodeUtil.addImportAll("org.springframework.web.bind.annotation");
        TemplateUtil.genAuthor(generate);
        ControllerTemplate.genImport(generate);
        ControllerTemplate.getClazzBody(generate);

        // 生成文件
        String filePath = GenerateUtil.getJavaFilePathNew(generate, "controller", "Controller");
        try {
            GenerateUtil.generateFile(filePath, CodeUtil.save());
        } catch (FileAlreadyExistsException e) {
            return GenerateUtil.fileExist(filePath);
        }
        return filePath;
    }
}
